package com.mall.common.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author Darren
 * @date 2022-10-20 9:08
 * Description：
 */
public class JwtToken {
    /**
     * 默认密钥
     */
    private static final String DEFAULT_SECRET = "darren";

    private static Algorithm getAlgorithm(String secret) {
        // 密钥为空就使用默认密钥
        if (secret == null)
            secret = DEFAULT_SECRET;
        // 创建令牌操作算法
        return Algorithm.HMAC256(secret);
    }

    /**
     * 生成密钥
     *
     * @param dataMap
     * @return
     */
    public static String createToken(Map<String, Object> dataMap) {
        return createToken(dataMap, null);
    }

    /**
     * 生成密钥
     *
     * @param dataMap
     * @param secret
     * @return
     */
    public static String createToken(Map<String, Object> dataMap, String secret) {
        Algorithm algorithm = getAlgorithm(secret);
        // 创建令牌
        return JWT.create()
                // JWT签发着
                .withIssuer("Darren")
                // 主题
                .withSubject("JWT令牌")
                // 接收JWT的一方
                .withAudience("member")
                // 过期时间
                .withExpiresAt(new Date(System.currentTimeMillis() + 3600000))
                // 指定时间之前jwt是不可用的
                .withNotBefore(new Date(System.currentTimeMillis()))
                // jwt的签发时间
                .withIssuedAt(new Date())
                // jwt的唯一标识
                .withJWTId(UUID.randomUUID().toString().replace("-", ""))
                // 额外参数
                .withClaim("body", dataMap)
                .sign(algorithm);
    }

    /**
     * 令牌校验并解析
     *
     * @param token
     * @return
     */
    public static Map<String, Object> parseToken(String token) {
        return parseToken(token, null);
    }

    /**
     * 令牌校验并解析
     *
     * @param token
     * @param secret
     * @return
     */
    public static Map<String, Object> parseToken(String token, String secret) {
        // 密钥为空就使用默认密钥
        Algorithm algorithm = getAlgorithm(secret);
        JWTVerifier verifier = JWT.require(algorithm).build();
        DecodedJWT jwt = verifier.verify(token);
        return jwt.getClaim("body").as(Map.class);
    }

    public static void main(String[] args) {
        Map<String, Object> map = new HashMap<>();
        map.put("name", "lisa");
        map.put("age", "18");

        String token = createToken(map);
        System.out.println(token);

        Map<String, Object> parse = parseToken(token);
        System.out.println(parse);
    }
}
